<!DOCTYPE html>
<html lang="en-US">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>面试-网络基础TCP和UDP的知识 | 惊蛰的博客</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.11.2/css/all.css">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.11.2/css/v4-shims.css">
    <script src="https://use.fontawesome.com/releases/v5.11.2/js/all.js"></script>
    <script src="https://use.fontawesome.com/releases/v5.11.2/js/v4-shims.js"></script>
    <!--    #代码高亮引入必要库-->
    <link href="https://cdn.bootcss.com/highlight.js/8.0/styles/monokai_sublime.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/highlight.js/8.0/highlight.min.js"></script>
    <!--    动画库-->
    <link rel="stylesheet" href="https://www.kettle.net.cn/animate/animate.min.css">
    <!--    评论-->
    <script src="//unpkg.com/valine/dist/Valine.min.js"></script>
    <!--    aplayer-->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer@1.10.0/dist/APlayer.min.css">
    <script src="https://cdn.jsdelivr.net/npm/aplayer@1.10.0/dist/APlayer.min.js"></script>
    <!-- require MetingJS -->
    <script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>
    <!--    jq-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <!--    backstretch 轮播图-->
    <script type="text/javascript" src="//cdn.bootcss.com/jquery-backstretch/2.0.4/jquery.backstretch.min.js"></script>
    <!-- 引用 bbtalk -->
    <script src="https://cdn.jsdelivr.net/npm/bbtalk@0.1.5/dist/bbtalk.min.js"></script>
    
    <meta name="description" content="惊蛰的博客">
    
    <link rel="preload" href="/assets/css/0.styles.c076dd71.css" as="style"><link rel="preload" href="/assets/js/app.8e64649f.js" as="script"><link rel="preload" href="/assets/js/17.9b1a1e45.js" as="script"><link rel="preload" href="/assets/js/4.84c4889c.js" as="script"><link rel="preload" href="/assets/js/40.76c692f0.js" as="script"><link rel="prefetch" href="/assets/js/1.19f63e1b.js"><link rel="prefetch" href="/assets/js/10.76457569.js"><link rel="prefetch" href="/assets/js/11.2fabe50b.js"><link rel="prefetch" href="/assets/js/12.29f3cbb3.js"><link rel="prefetch" href="/assets/js/13.5bbd6907.js"><link rel="prefetch" href="/assets/js/14.97c38b2b.js"><link rel="prefetch" href="/assets/js/15.a6ea704f.js"><link rel="prefetch" href="/assets/js/16.bf8c8fc8.js"><link rel="prefetch" href="/assets/js/18.bcc6785d.js"><link rel="prefetch" href="/assets/js/19.af8c6c71.js"><link rel="prefetch" href="/assets/js/2.63f6fb06.js"><link rel="prefetch" href="/assets/js/20.04b27695.js"><link rel="prefetch" href="/assets/js/21.0ecdd73f.js"><link rel="prefetch" href="/assets/js/22.5a2b263f.js"><link rel="prefetch" href="/assets/js/23.a9412068.js"><link rel="prefetch" href="/assets/js/24.aedb6bde.js"><link rel="prefetch" href="/assets/js/25.dfc2456b.js"><link rel="prefetch" href="/assets/js/26.e8e572f6.js"><link rel="prefetch" href="/assets/js/27.0fd0718f.js"><link rel="prefetch" href="/assets/js/28.60ae6b13.js"><link rel="prefetch" href="/assets/js/29.701ebcc0.js"><link rel="prefetch" href="/assets/js/3.315403c1.js"><link rel="prefetch" href="/assets/js/30.9b75bf1e.js"><link rel="prefetch" href="/assets/js/31.67f8b095.js"><link rel="prefetch" href="/assets/js/32.b87582bb.js"><link rel="prefetch" href="/assets/js/33.7c0ab263.js"><link rel="prefetch" href="/assets/js/34.d4c2e482.js"><link rel="prefetch" href="/assets/js/35.88a27070.js"><link rel="prefetch" href="/assets/js/36.ccd7bbb9.js"><link rel="prefetch" href="/assets/js/37.a4ec9e64.js"><link rel="prefetch" href="/assets/js/38.888b51fa.js"><link rel="prefetch" href="/assets/js/39.822d40c5.js"><link rel="prefetch" href="/assets/js/5.94499d86.js"><link rel="prefetch" href="/assets/js/6.5934ba2a.js"><link rel="prefetch" href="/assets/js/8.b3a395d6.js"><link rel="prefetch" href="/assets/js/9.81a3105a.js">
    <link rel="stylesheet" href="/assets/css/0.styles.c076dd71.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div><div data-v-43936cb4><div class="container" data-v-43936cb4 data-v-43936cb4><div class="ordinary" data-v-43936cb4><div data-v-43936cb4><a target="_self" href="/" class="title flat-box waves-effect waves-block author" data-v-43936cb4>
                        jingzhe
                    </a></div> <div class="menu navigation" data-v-43936cb4><ul class="nav-list-h m-pc" data-v-43936cb4><li data-v-43936cb4><a href="/" id="home" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-home fa-fw" data-v-43936cb4></i>博客
                            </a></li> <li data-v-43936cb4><a href="/archives/" id="archives" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-archive fa-fw" data-v-43936cb4></i>归档
                            </a></li> <li data-v-43936cb4><a href="/friends/" id="friends" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-link fa-fw" data-v-43936cb4></i>友链
                            </a></li> <li data-v-43936cb4><a href="/aboutPage/" id="about" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-info-circle fa-fw" data-v-43936cb4></i>关于
                            </a></li> <li data-v-43936cb4><a id="other" class="menuitem flat-box faa-parent animated-hover waves-effect waves-block" data-v-43936cb4><i class="fa fa-info-circle fa-fw" data-v-43936cb4></i>其他
                            </a> <ul class="list-v" data-v-43936cb4><li data-v-43936cb4><a class="menuitem flat-box header toggle-mode-btn cutover" data-v-43936cb4><i class="fas fa-moon fa-fw" data-v-43936cb4></i> 暗黑模式
                                    </a></li> <li data-v-43936cb4><hr data-v-43936cb4></li> <li data-v-43936cb4><a href="/bb/" class="menuitem flat-box faa-parent animated-hover" data-v-43936cb4>
                                        哔哔哔
                                    </a></li> <li data-v-43936cb4><a target="_blank" href="https://blog.jingzhe.xyz" class="menuitem flat-box faa-parent animated-hover" data-v-43936cb4>
                                        旧版博客
                                    </a></li> <hr data-v-43936cb4> <li data-v-43936cb4><a href="/categories/" class="menuitem flat-box faa-parent animated-hover" data-v-43936cb4><i class="fa fa-folder-open fa-fw" data-v-43936cb4></i>
                                        分类
                                    </a></li> <li data-v-43936cb4><a href="/tags/" id="v2getting-started" class="menuitem flat-box faa-parent animated-hover" data-v-43936cb4><i class="fa fa-tags fa-fw" data-v-43936cb4></i> 标签
                                    </a></li></ul></li></ul></div> <div class="m_search" data-v-43936cb4><form name="searchform" class="form u-search-form" data-v-43936cb4><i class="icon fa fa-search fa-fw" data-v-43936cb4></i> <input type="text" placeholder="Search..." class="input u-search-input" data-v-43936cb4></form></div></div> <div class="paper" data-v-43936cb4></div></div></div> <div id="archives-pjax" class="paper" data-v-bb8ac3a0><div class="homeCover" data-v-bb8ac3a0></div> <div class="row" data-v-bb8ac3a0><div class="col-span-24" data-v-bb8ac3a0><div id="anchorPoint" data-v-bb8ac3a0></div></div> <div id="main-body-pjax" class="main-body" data-v-bb8ac3a0><div class="paper-page" data-v-bb8ac3a0><div show="true" class="homepage" data-v-9fc62fe0 data-v-bb8ac3a0><div class="post-list" data-v-9fc62fe0 data-v-9fc62fe0><div class="post-wrapper" data-v-9fc62fe0><div class="headimg-div" data-v-9fc62fe0><!----></div> <div class="meta" data-v-9fc62fe0><h2 data-v-9fc62fe0>面试-网络基础TCP和UDP的知识</h2> <div data-v-9fc62fe0><div class="author" data-v-9fc62fe0><a href="https://blog.jingzhe.xyz" rel="nofollow" class="author-div" data-v-9fc62fe0><img src="https://blog.jingzhe.xyz/jingzhe/jpg/1593256062295.jpeg" data-v-9fc62fe0> <a data-v-9fc62fe0>Jingzhe</a></a></div> <div class="time" data-v-9fc62fe0><div data-v-9fc62fe0><i aria-hidden="true" class="fa fa-calendar-alt fa-fw" data-v-9fc62fe0></i> <span data-v-9fc62fe0>2020-11-30T13:41:35.000Z</span></div></div> <div class="guest" data-v-9fc62fe0><i class="fa fa-comment-dots fa-fw" data-v-9fc62fe0></i> <span data-v-9fc62fe0>9</span></div></div></div> <div class="article" data-v-9fc62fe0><div class="leancloud_visitors" data-v-9fc62fe0><div class="content__default" data-v-9fc62fe0><h1 id="基本记录一下网络基础-tcp和udp-的知识"><a href="#基本记录一下网络基础-tcp和udp-的知识" class="header-anchor">#</a> 基本记录一下网络基础(TCP和UDP)的知识</h1> <p><img src="https://i.loli.net/2020/11/30/QRPdCHF1eL3kGB2.png" alt=""></p> <h2 id="udp和tcp"><a href="#udp和tcp" class="header-anchor">#</a> UDP和TCP</h2> <h3 id="udp"><a href="#udp" class="header-anchor">#</a> UDP</h3> <p><strong>首先说一下概念，UDP是一种无连接传输层协议，提供面向事务的简单不可靠的信息传输服务</strong></p> <h4 id="特点"><a href="#特点" class="header-anchor">#</a> 特点：</h4> <p><strong>1.udp是无连接的，也就是发送数据包无需建立连接，并因此减少了开销和发送数据之前不必要的时延</strong></p> <p><strong>2.使用尽量努力交付数据</strong></p> <p><strong>3.是面向报文的</strong></p> <h4 id="可能你会有这样的疑问-那么为什么不直接使用ip协议而是要重新定义出一个udp呢"><a href="#可能你会有这样的疑问-那么为什么不直接使用ip协议而是要重新定义出一个udp呢" class="header-anchor">#</a> 可能你会有这样的疑问？那么为什么不直接使用IP协议而是要重新定义出一个UDP呢？</h4> <p><strong>一个重要的原因的是IP协议并没有端口，UDP可以多通道，将数据送到对应的接口里面去</strong></p> <h2 id="tcp"><a href="#tcp" class="header-anchor">#</a> TCP</h2> <p><strong>首先说一下概念，TCP是一种面向连接、可靠、基于字节流的传输协议，属于5层或者7层网络协议中的传输层协议</strong></p> <h3 id="特点-2"><a href="#特点-2" class="header-anchor">#</a> 特点：</h3> <p><strong>面向连接：不同于UDP，TCP协议需要通信双方确定彼此已经建立连接后才可以进行数据传输；</strong></p> <p><strong>可靠：连接建立的双方在进行通信时，TCP保证了不会存在数据丢失，或是数据丢失后存在拯救丢失的措施；字节流：实际传输中，不论是何种数据，TCP都按照字节的方式传输，而非以数据包为单位。</strong></p> <h3 id="说一下tcp的三次握手-四次挥手-和具体每一步的操作和作用"><a href="#说一下tcp的三次握手-四次挥手-和具体每一步的操作和作用" class="header-anchor">#</a> 说一下TCP的三次握手，四次挥手，和具体每一步的操作和作用</h3> <h4 id="简单介绍一下tcp的报文"><a href="#简单介绍一下tcp的报文" class="header-anchor">#</a> 简单介绍一下TCP的报文</h4> <p><img src="https://i.loli.net/2020/11/30/U48dMHArty5p9jc.png" alt=""></p> <table data-draft-node="block" data-draft-type="table" data-size="normal"><tbody><tr><th>字段</th><th>含义</th></tr><tr><td>URG</td><td>紧急指针是否有效。为1，表示某一位需要被优先处理</td></tr><tr><td>ACK</td><td>确认号是否有效，一般置为1。</td></tr><tr><td>PSH</td><td>提示接收端应用程序立即从TCP缓冲区把数据读走。</td></tr><tr><td>RST</td><td>对方要求重新建立连接，复位。</td></tr><tr><td>SYN</td><td>请求建立连接，并在其序列号的字段进行序列号的初始值设定。建立连接，设置为1</td></tr><tr><td>FIN</td><td>希望断开连接。</td></tr></tbody></table> <h3 id="三次握手"><a href="#三次握手" class="header-anchor">#</a> 三次握手</h3> <p><img src="https://i.loli.net/2020/11/30/igLxPYQImepJ6Nj.png" alt="三次握手示意图"></p> <h6 id="第一次握手-建立连接时-客户端发送syn包-syn-x-到服务器-并进入syn-sent状态-等待服务器确认-syn-同步序列编号-synchronize-sequence-numbers"><a href="#第一次握手-建立连接时-客户端发送syn包-syn-x-到服务器-并进入syn-sent状态-等待服务器确认-syn-同步序列编号-synchronize-sequence-numbers" class="header-anchor">#</a> 第一次握手：建立连接时，客户端发送syn包（syn=x）到服务器，并进入<strong>SYN_SENT</strong>状态，等待服务器确认；SYN：同步序列编号（Synchronize Sequence Numbers）</h6> <p>保证了客户端发送正常</p> <h6 id="第二次握手-服务器收到syn包-必须确认客户的syn-ack-x-1-同时自己也发送一个syn包-syn-y-即syn-ack包-此时服务器进入syn-recv状态"><a href="#第二次握手-服务器收到syn包-必须确认客户的syn-ack-x-1-同时自己也发送一个syn包-syn-y-即syn-ack包-此时服务器进入syn-recv状态" class="header-anchor">#</a> 第二次握手：服务器收到syn包，必须确认客户的SYN（ack=x+1），同时自己也发送一个SYN包（syn=y），即SYN+ACK包，此时服务器进入<strong>SYN_RECV</strong>状态；</h6> <p>保证了服务端接受正常，发送正常</p> <h6 id="第三次握手-客户端收到服务器的syn-ack包-向服务器发送确认包ack-ack-y-1-此包发送完毕-客户端和服务器进入established-tcp连接成功-状态-完成三次握手。"><a href="#第三次握手-客户端收到服务器的syn-ack包-向服务器发送确认包ack-ack-y-1-此包发送完毕-客户端和服务器进入established-tcp连接成功-状态-完成三次握手。" class="header-anchor">#</a> 第三次握手：客户端收到服务器的SYN+ACK包，向服务器发送确认包ACK(ack=y+1），此包发送完毕，客户端和服务器进入<strong>ESTABLISHED</strong>（TCP连接成功）状态，完成三次握手。</h6> <p>保证了客户端接受正常，创建连接成功，开始工作</p> <h3 id="四次挥手"><a href="#四次挥手" class="header-anchor">#</a> 四次挥手</h3> <p><img src="https://i.loli.net/2020/11/30/GQpdIMNCA8PmKfh.png" alt="四次挥手示意图"></p> <h6 id="_1-客户端进程发出连接释放报文-并且停止发送数据。释放数据报文首部-fin-1-其序列号为seq-u-等于前面已经传送过来的数据的最后一个字节的序号加1-此时-客户端进入fin-wait-1-终止等待1-状态。-tcp规定-fin报文段即使不携带数据-也要消耗一个序号。"><a href="#_1-客户端进程发出连接释放报文-并且停止发送数据。释放数据报文首部-fin-1-其序列号为seq-u-等于前面已经传送过来的数据的最后一个字节的序号加1-此时-客户端进入fin-wait-1-终止等待1-状态。-tcp规定-fin报文段即使不携带数据-也要消耗一个序号。" class="header-anchor">#</a> 1）客户端进程发出连接释放报文，并且停止发送数据。释放数据报文首部，FIN=1，其序列号为seq=u（等于前面已经传送过来的数据的最后一个字节的序号加1），此时，客户端进入FIN-WAIT-1（终止等待1）状态。 TCP规定，FIN报文段即使不携带数据，也要消耗一个序号。</h6> <h6 id="服务器收到连接释放报文-发出确认报文-ack-1-ack-u-1-并且带上自己的序列号seq-v-此时-服务端就进入了close-wait-关闭等待-状态。tcp服务器通知高层的应用进程-客户端向服务器的方向就释放了-这时候处于半关闭状态-即客户端已经没有数据要发送了-但是服务器若发送数据-客户端依然要接受。这个状态还要持续一段时间-也就是整个close-wait状态持续的时间。"><a href="#服务器收到连接释放报文-发出确认报文-ack-1-ack-u-1-并且带上自己的序列号seq-v-此时-服务端就进入了close-wait-关闭等待-状态。tcp服务器通知高层的应用进程-客户端向服务器的方向就释放了-这时候处于半关闭状态-即客户端已经没有数据要发送了-但是服务器若发送数据-客户端依然要接受。这个状态还要持续一段时间-也就是整个close-wait状态持续的时间。" class="header-anchor">#</a> 服务器收到连接释放报文，发出确认报文，ACK=1，ack=u+1，并且带上自己的序列号seq=v，此时，服务端就进入了CLOSE-WAIT（关闭等待）状态。TCP服务器通知高层的应用进程，客户端向服务器的方向就释放了，这时候处于半关闭状态，即客户端已经没有数据要发送了，但是服务器若发送数据，客户端依然要接受。这个状态还要持续一段时间，也就是整个CLOSE-WAIT状态持续的时间。</h6> <h6 id="中断中发送未完成数据流-客户端收到服务器的确认请求后-此时-客户端就进入fin-wait-2-终止等待2-状态-等待服务器发送连接释放报文-在这之前还需要接受服务器发送的最后的数据-。"><a href="#中断中发送未完成数据流-客户端收到服务器的确认请求后-此时-客户端就进入fin-wait-2-终止等待2-状态-等待服务器发送连接释放报文-在这之前还需要接受服务器发送的最后的数据-。" class="header-anchor">#</a> （中断中发送未完成数据流 ）客户端收到服务器的确认请求后，此时，客户端就进入FIN-WAIT-2（终止等待2）状态，等待服务器发送连接释放报文（在这之前还需要接受服务器发送的最后的数据）。</h6> <h6 id="_2-服务器将最后的数据发送完毕后-就向客户端发送连接释放报文-fin-1-ack-u-1-由于在半关闭状态-服务器很可能又发送了一些数据-假定此时的序列号为seq-w-此时-服务器就进入了last-ack-最后确认-状态-等待客户端的确认。"><a href="#_2-服务器将最后的数据发送完毕后-就向客户端发送连接释放报文-fin-1-ack-u-1-由于在半关闭状态-服务器很可能又发送了一些数据-假定此时的序列号为seq-w-此时-服务器就进入了last-ack-最后确认-状态-等待客户端的确认。" class="header-anchor">#</a> 2）服务器将最后的数据发送完毕后，就向客户端发送连接释放报文，FIN=1，ack=u+1，由于在半关闭状态，服务器很可能又发送了一些数据，假定此时的序列号为seq=w，此时，服务器就进入了LAST-ACK（最后确认）状态，等待客户端的确认。</h6> <h6 id="_3-客户端收到服务器的连接释放报文后-必须发出确认-ack-1-ack-w-1-而自己的序列号是seq-u-1-此时-客户端就进入了time-wait-时间等待-状态。注意此时tcp连接还没有释放-必须经过2∗∗msl-最长报文段寿命-的时间后-当客户端撤销相应的tcb后-才进入closed状态。"><a href="#_3-客户端收到服务器的连接释放报文后-必须发出确认-ack-1-ack-w-1-而自己的序列号是seq-u-1-此时-客户端就进入了time-wait-时间等待-状态。注意此时tcp连接还没有释放-必须经过2∗∗msl-最长报文段寿命-的时间后-当客户端撤销相应的tcb后-才进入closed状态。" class="header-anchor">#</a> 3）客户端收到服务器的连接释放报文后，必须发出确认，ACK=1，ack=w+1，而自己的序列号是seq=u+1，此时，客户端就进入了TIME-WAIT（时间等待）状态。注意此时TCP连接还没有释放，必须经过2∗∗MSL（最长报文段寿命）的时间后，当客户端撤销相应的TCB后，才进入CLOSED状态。</h6> <h6 id="_4-服务器只要收到了客户端发出的确认-立即进入closed状态。同样-撤销tcb后-就结束了这次的tcp连接。可以看到-服务器结束tcp连接的时间要比客户端早一些。"><a href="#_4-服务器只要收到了客户端发出的确认-立即进入closed状态。同样-撤销tcb后-就结束了这次的tcp连接。可以看到-服务器结束tcp连接的时间要比客户端早一些。" class="header-anchor">#</a> 4）服务器只要收到了客户端发出的确认，立即进入CLOSED状态。同样，撤销TCB后，就结束了这次的TCP连接。可以看到，服务器结束TCP连接的时间要比客户端早一些。</h6> <h3 id="关于tcp的面试题比较多一些-下面罗列几个面试题-网上总结的"><a href="#关于tcp的面试题比较多一些-下面罗列几个面试题-网上总结的" class="header-anchor">#</a> 关于TCP的面试题比较多一些，下面罗列几个面试题（网上总结的）：</h3> <h6 id="【问题1】为什么连接的时候是三次握手-关闭的时候却是四次握手"><a href="#【问题1】为什么连接的时候是三次握手-关闭的时候却是四次握手" class="header-anchor">#</a> 【问题1】为什么连接的时候是三次握手，关闭的时候却是四次握手？</h6> <h6 id="答-因为当server端收到client端的syn连接请求报文后-可以直接发送syn-ack报文。其中ack报文是用来应答的-syn报文是用来同步的。但是关闭连接时-当server端收到fin报文时-很可能并不会立即关闭socket-所以只能先回复一个ack报文-告诉client端-你发的fin报文我收到了-。只有等到我server端所有的报文都发送完了-我才能发送fin报文-因此不能一起发送。故需要四步握手。"><a href="#答-因为当server端收到client端的syn连接请求报文后-可以直接发送syn-ack报文。其中ack报文是用来应答的-syn报文是用来同步的。但是关闭连接时-当server端收到fin报文时-很可能并不会立即关闭socket-所以只能先回复一个ack报文-告诉client端-你发的fin报文我收到了-。只有等到我server端所有的报文都发送完了-我才能发送fin报文-因此不能一起发送。故需要四步握手。" class="header-anchor">#</a> 答：因为当Server端收到Client端的SYN连接请求报文后，可以直接发送SYN+ACK报文。其中ACK报文是用来应答的，SYN报文是用来同步的。但是关闭连接时，当Server端收到FIN报文时，很可能并不会立即关闭SOCKET，所以只能先回复一个ACK报文，告诉Client端，&quot;你发的FIN报文我收到了&quot;。只有等到我Server端所有的报文都发送完了，我才能发送FIN报文，因此不能一起发送。故需要四步握手。</h6> <h6 id="【问题2】为什么time-wait状态需要经过2msl-最大报文段生存时间-才能返回到close状态"><a href="#【问题2】为什么time-wait状态需要经过2msl-最大报文段生存时间-才能返回到close状态" class="header-anchor">#</a> 【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态？</h6> <h6 id="答-虽然按道理-四个报文都发送完毕-我们可以直接进入close状态了-但是我们必须假象网络是不可靠的-有可以最后一个ack丢失。所以time-wait状态就是用来重发可能丢失的ack报文。在client发送出最后的ack回复-但该ack可能丢失。server如果没有收到ack-将不断重复发送fin片段。所以client不能立即关闭-它必须确认server接收到了该ack。client会在发送出ack之后进入到time-wait状态。client会设置一个计时器-等待2msl的时间。如果在该时间内再次收到fin-那么client会重发ack并再次等待2msl。所谓的2msl是两倍的msl-maximum-segment-lifetime-。msl指一个片段在网络中最大的存活时间-2msl就是一个发送和一个回复所需的最大时间。如果直到2msl-client都没有再次收到fin-那么client推断ack已经被成功接收-则结束tcp连接。"><a href="#答-虽然按道理-四个报文都发送完毕-我们可以直接进入close状态了-但是我们必须假象网络是不可靠的-有可以最后一个ack丢失。所以time-wait状态就是用来重发可能丢失的ack报文。在client发送出最后的ack回复-但该ack可能丢失。server如果没有收到ack-将不断重复发送fin片段。所以client不能立即关闭-它必须确认server接收到了该ack。client会在发送出ack之后进入到time-wait状态。client会设置一个计时器-等待2msl的时间。如果在该时间内再次收到fin-那么client会重发ack并再次等待2msl。所谓的2msl是两倍的msl-maximum-segment-lifetime-。msl指一个片段在网络中最大的存活时间-2msl就是一个发送和一个回复所需的最大时间。如果直到2msl-client都没有再次收到fin-那么client推断ack已经被成功接收-则结束tcp连接。" class="header-anchor">#</a> 答：虽然按道理，四个报文都发送完毕，我们可以直接进入CLOSE状态了，但是我们必须假象网络是不可靠的，有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复，但该ACK可能丢失。Server如果没有收到ACK，将不断重复发送FIN片段。所以Client不能立即关闭，它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器，等待2MSL的时间。如果在该时间内再次收到FIN，那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间，2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL，Client都没有再次收到FIN，那么Client推断ACK已经被成功接收，则结束TCP连接。</h6> <h6 id="【问题3】为什么不能用两次握手进行连接"><a href="#【问题3】为什么不能用两次握手进行连接" class="header-anchor">#</a> 【问题3】为什么不能用两次握手进行连接？</h6> <h6 id="答-3次握手完成两个重要的功能-既要双方做好发送数据的准备工作-双方都知道彼此已准备好-也要允许双方就初始序列号进行协商-这个序列号在握手过程中被发送和确认。"><a href="#答-3次握手完成两个重要的功能-既要双方做好发送数据的准备工作-双方都知道彼此已准备好-也要允许双方就初始序列号进行协商-这个序列号在握手过程中被发送和确认。" class="header-anchor">#</a> 答：3次握手完成两个重要的功能，既要双方做好发送数据的准备工作(双方都知道彼此已准备好)，也要允许双方就初始序列号进行协商，这个序列号在握手过程中被发送和确认。</h6> <p>###### 现在把三次握手改成仅需要两次握手，死锁是可能发生的。作为例子，考虑计算机S和C之间的通信，假定C给S发送一个连接请求分组，S收到了这个分组，并发 送了确认应答分组。按照两次握手的协定，S认为连接已经成功地建立了，可以开始发送数据分组。可是，C在S的应答分组在传输中被丢失的情况下，将不知道S 是否已准备好，不知道S建立什么样的序列号，C甚至怀疑S是否收到自己的连接请求分组。在这种情况下，C认为连接还未建立成功，将忽略S发来的任何数据分 组，只等待连接确认应答分组。而S在发出的分组超时后，重复发送同样的分组。这样就形成了死锁。</p> <h6 id="【问题4】如果已经建立了连接-但是客户端突然出现故障了怎么办-tcp还设有一个保活计时器-显然-客户端如果出现故障-服务器不能一直等下去-白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器-时间通常是设置为2小时-若两小时还没有收到客户端的任何数据-服务器就会发送一个探测报文段-以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应-服务器就认为客户端出了故障-接着就关闭连接。"><a href="#【问题4】如果已经建立了连接-但是客户端突然出现故障了怎么办-tcp还设有一个保活计时器-显然-客户端如果出现故障-服务器不能一直等下去-白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器-时间通常是设置为2小时-若两小时还没有收到客户端的任何数据-服务器就会发送一个探测报文段-以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应-服务器就认为客户端出了故障-接着就关闭连接。" class="header-anchor">#</a> 【问题4】如果已经建立了连接，但是客户端突然出现故障了怎么办？TCP还设有一个保活计时器，显然，客户端如果出现故障，服务器不能一直等下去，白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器，时间通常是设置为2小时，若两小时还没有收到客户端的任何数据，服务器就会发送一个探测报文段，以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应，服务器就认为客户端出了故障，接着就关闭连接。</h6> <h3 id="说一下tcp和udp有什么不同处"><a href="#说一下tcp和udp有什么不同处" class="header-anchor">#</a> 说一下TCP和UDP有什么不同处</h3> <h6 id="_1、-tcp面向连接-如打电话要先拨号建立连接-udp是无连接-的-即发送数据之前不需要建立连接"><a href="#_1、-tcp面向连接-如打电话要先拨号建立连接-udp是无连接-的-即发送数据之前不需要建立连接" class="header-anchor">#</a> 1、 TCP面向连接 （如打电话要先拨号建立连接）; UDP是无连接 的，即发送数据之前不需要建立连接</h6> <h6 id="_2、tcp提供可靠的服务。也就是说-通过tcp连接传送的数据-无差错-不丢失-不重复-且按序到达-udp尽最大努力交付-即不保证可靠交付"><a href="#_2、tcp提供可靠的服务。也就是说-通过tcp连接传送的数据-无差错-不丢失-不重复-且按序到达-udp尽最大努力交付-即不保证可靠交付" class="header-anchor">#</a> 2、TCP提供可靠的服务。也就是说，通过TCP连接传送的数据，无差错，不丢失，不重复，且按序到达;UDP尽最大努力交付，即不保证可靠交付</h6> <h6 id="tcp通过校验和-重传控制-序号标识-滑动窗口、确认应答实现可靠传输。如丢包时的重发控制-还可以对次序乱掉的分包进行顺序控制。"><a href="#tcp通过校验和-重传控制-序号标识-滑动窗口、确认应答实现可靠传输。如丢包时的重发控制-还可以对次序乱掉的分包进行顺序控制。" class="header-anchor">#</a> Tcp通过校验和，重传控制，序号标识，滑动窗口、确认应答实现可靠传输。如丢包时的重发控制，还可以对次序乱掉的分包进行顺序控制。</h6> <h6 id="_3、udp具有较好的实时性-工作效率比tcp高-适用于对高速传输和实时性有较高的通信或广播通信。"><a href="#_3、udp具有较好的实时性-工作效率比tcp高-适用于对高速传输和实时性有较高的通信或广播通信。" class="header-anchor">#</a> 3、UDP具有较好的实时性，工作效率比TCP高，适用于对高速传输和实时性有较高的通信或广播通信。</h6> <h6 id="_4-每一条tcp连接只能是点到点的-udp支持一对一-一对多-多对一和多对多的交互通信"><a href="#_4-每一条tcp连接只能是点到点的-udp支持一对一-一对多-多对一和多对多的交互通信" class="header-anchor">#</a> 4.每一条TCP连接只能是点到点的;UDP支持一对一，一对多，多对一和多对多的交互通信</h6> <h6 id="_5、tcp对系统资源要求较多-udp对系统资源要求较少。"><a href="#_5、tcp对系统资源要求较多-udp对系统资源要求较少。" class="header-anchor">#</a> 5、TCP对系统资源要求较多，UDP对系统资源要求较少。</h6> <h3 id="tcp那么好-那么为什么还需要udp-udp相对的优势在哪里"><a href="#tcp那么好-那么为什么还需要udp-udp相对的优势在哪里" class="header-anchor">#</a> TCP那么好，那么为什么还需要UDP，UDP相对的优势在哪里</h3> <h6 id="udp以其简单、传输快的优势-在越来越多场景下取代了tcp-如实时游戏。"><a href="#udp以其简单、传输快的优势-在越来越多场景下取代了tcp-如实时游戏。" class="header-anchor">#</a> UDP以其简单、传输快的优势，在越来越多场景下取代了TCP,如实时游戏。</h6> <h6 id="_1-网速的提升给udp的稳定性提供可靠网络保障-丢包率很低-如果使用应用层重传-能够确保传输的可靠性。"><a href="#_1-网速的提升给udp的稳定性提供可靠网络保障-丢包率很低-如果使用应用层重传-能够确保传输的可靠性。" class="header-anchor">#</a> （1）网速的提升给UDP的稳定性提供可靠网络保障，丢包率很低，如果使用应用层重传，能够确保传输的可靠性。</h6> <h6 id="_2-tcp为了实现网络通信的可靠性-使用了复杂的拥塞控制算法-建立了繁琐的握手过程-由于tcp内置的系统协议栈中-极难对其进行改进。"><a href="#_2-tcp为了实现网络通信的可靠性-使用了复杂的拥塞控制算法-建立了繁琐的握手过程-由于tcp内置的系统协议栈中-极难对其进行改进。" class="header-anchor">#</a> （2）TCP为了实现网络通信的可靠性，使用了复杂的拥塞控制算法，建立了繁琐的握手过程，由于TCP内置的系统协议栈中，极难对其进行改进。</h6> <h6 id="采用tcp-一旦发生丢包-tcp会将后续的包缓存起来-等前面的包重传并接收到后再继续发送-延时会越来越大-基于udp对实时性要求较为严格的情况下-采用自定义重传机制-能够把丢包产生的延迟降到最低-尽量减少网络问题对游戏性造成影响。"><a href="#采用tcp-一旦发生丢包-tcp会将后续的包缓存起来-等前面的包重传并接收到后再继续发送-延时会越来越大-基于udp对实时性要求较为严格的情况下-采用自定义重传机制-能够把丢包产生的延迟降到最低-尽量减少网络问题对游戏性造成影响。" class="header-anchor">#</a> 采用TCP，一旦发生丢包，TCP会将后续的包缓存起来，等前面的包重传并接收到后再继续发送，延时会越来越大，基于UDP对实时性要求较为严格的情况下，采用自定义重传机制，能够把丢包产生的延迟降到最低，尽量减少网络问题对游戏性造成影响。</h6> <h3 id="如何让udp更不易丢包-变成可靠的udp呢"><a href="#如何让udp更不易丢包-变成可靠的udp呢" class="header-anchor">#</a> 如何让UDP更不易丢包，变成可靠的UDP呢？</h3> <h6 id="我觉得这个问题比较复杂-咱们可以单独开一篇文章说明"><a href="#我觉得这个问题比较复杂-咱们可以单独开一篇文章说明" class="header-anchor">#</a> 我觉得这个问题比较复杂，咱们可以单独开一篇文章说明</h6> <h6 id="以上就是我整理的tcp和udp的相关面试知识"><a href="#以上就是我整理的tcp和udp的相关面试知识" class="header-anchor">#</a> 以上就是我整理的TCP和UDP的相关面试知识</h6> <h6 id="新博客-https-jingzhe-xyz"><a href="#新博客-https-jingzhe-xyz" class="header-anchor">#</a> 新博客 ：https://jingzhe.xyz</h6></div></div></div> <div data-v-9fc62fe0><div class="article_copyright" data-v-089751b8 data-v-9fc62fe0><div class="article_footer" data-v-089751b8><div class="content" data-v-089751b8><blockquote data-v-089751b8><p data-v-089751b8>博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议</p> <p data-v-089751b8>本文永久链接是：<a href="/2020/11/30/%E9%9D%A2%E8%AF%95-%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80tcp%E5%92%8Cudp%E7%9A%84%E7%9F%A5%E8%AF%86/" style="display: block;" data-v-089751b8>/2020/11/30/%E9%9D%A2%E8%AF%95-%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80tcp%E5%92%8Cudp%E7%9A%84%E7%9F%A5%E8%AF%86/</a></p></blockquote></div></div> <div class="new-meta-box" data-v-089751b8><div itemprop="dateUpdated" class="new-date" data-v-089751b8><a data-v-089751b8><i aria-hidden="true" class="fa fa-edit fa-fw" data-v-089751b8></i> <p data-v-089751b8>更新于：2020-11-30T13:41:35.000Z</p></a></div></div> <div class="prev-next" data-v-089751b8><a href="/2020/11/30/%E9%9D%A2%E8%AF%95-%E7%AE%80%E8%AE%BAhttp%E5%92%8Chttps%E6%95%96%E4%B8%99%E9%9D%A2%E8%AF%95%E5%9B%BE%E8%A7%A3%E6%9E%90/" class="prev" data-v-089751b8><p class="title" data-v-089751b8><i aria-hidden="true" class="fa fa-chevron-left" data-v-089751b8></i>面试-网络基础TCP和UDP的知识</p></a> <a href="/2021/01/24/jenkins%E9%83%A8%E7%BD%B2java%E7%9A%84%E5%85%A8%E9%83%A8%E6%95%99%E7%A8%8B-%E6%84%9F%E5%8F%97jenkins%E7%9A%84%E5%B7%A8%E5%A4%A7%E9%AD%85%E5%8A%9B/" class="next" data-v-089751b8><p class="title" data-v-089751b8>Jenkins部署JAVA的全部教程，感受Jenkins的巨大魅力<i aria-hidden="true" class="fa fa-chevron-right" data-v-089751b8></i></p></a></div></div></div></div> <div class="article-comment" data-v-9fc62fe0><div class="comment" data-v-2ce08322 data-v-9fc62fe0><div class="post-list" data-v-2ce08322><div class="post-wrapper vcomment-div" data-v-2ce08322><em class="post-meta-item-text" data-v-2ce08322>阅读量 </em> <i class="leancloud-visitors-count" data-v-2ce08322>1000000</i> <div data-v-2ce08322></div></div></div></div></div></div></div></div> <div class="right-page" data-v-bb8ac3a0><div class="rightPage" data-v-1be37983 data-v-bb8ac3a0><div class="computer" data-v-1be37983 data-v-1be37983><div class="content paperMenu" style="transition:0s;" data-v-1be37983><div class="social-wrapper paper-navigation" data-v-1be37983><div data-v-1be37983><i class="fas fa-folder-open fa-fw" data-v-1be37983></i> <span data-v-1be37983>文章导航</span></div> <div class="navigationContent" data-v-1be37983><div data-v-1be37983><h1 class="paperlevel" data-v-1be37983><a id="基本记录一下网络基础-tcp和udp-的知识" data-v-1be37983></a>基本记录一下网络基础(TCP和UDP)的知识
                            </h1> <!----> <!----> <!----> <!----> <!----></div><div data-v-1be37983><!----> <h2 class="paperlevel" data-v-1be37983><a id="udp和tcp" data-v-1be37983></a>UDP和TCP
                            </h2> <!----> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="udp" data-v-1be37983></a>UDP
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <!----> <h4 class="paperlevel" data-v-1be37983><a id="特点" data-v-1be37983></a>特点：
                            </h4> <!----> <!----></div><div data-v-1be37983><!----> <!----> <!----> <h4 class="paperlevel" data-v-1be37983><a id="可能你会有这样的疑问-那么为什么不直接使用ip协议而是要重新定义出一个udp呢" data-v-1be37983></a>可能你会有这样的疑问？那么为什么不直接使用IP协议而是要重新定义出一个UDP呢？
                            </h4> <!----> <!----></div><div data-v-1be37983><!----> <h2 class="paperlevel" data-v-1be37983><a id="tcp" data-v-1be37983></a>TCP
                            </h2> <!----> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="特点-2" data-v-1be37983></a>特点：
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="说一下tcp的三次握手-四次挥手-和具体每一步的操作和作用" data-v-1be37983></a>说一下TCP的三次握手，四次挥手，和具体每一步的操作和作用
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <!----> <h4 class="paperlevel" data-v-1be37983><a id="简单介绍一下tcp的报文" data-v-1be37983></a>简单介绍一下TCP的报文
                            </h4> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="三次握手" data-v-1be37983></a>三次握手
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="四次挥手" data-v-1be37983></a>四次挥手
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="关于tcp的面试题比较多一些-下面罗列几个面试题-网上总结的" data-v-1be37983></a>关于TCP的面试题比较多一些，下面罗列几个面试题（网上总结的）：
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="说一下tcp和udp有什么不同处" data-v-1be37983></a>说一下TCP和UDP有什么不同处
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="tcp那么好-那么为什么还需要udp-udp相对的优势在哪里" data-v-1be37983></a>TCP那么好，那么为什么还需要UDP，UDP相对的优势在哪里
                            </h3> <!----> <!----> <!----></div><div data-v-1be37983><!----> <!----> <h3 class="paperlevel" data-v-1be37983><a id="如何让udp更不易丢包-变成可靠的udp呢" data-v-1be37983></a>如何让UDP更不易丢包，变成可靠的UDP呢？
                            </h3> <!----> <!----> <!----></div></div></div></div> <div class="content" data-v-1be37983><div class="head" data-v-1be37983><a href="/aboutPage/" class="avatar flat-box rectangle" data-v-1be37983><img src="https://blog.jingzhe.xyz/jingzhe/jpg/1593256062295.jpeg" data-v-1be37983></a> <p data-v-1be37983><span data-v-1be37983>微雨众卉新，一雷惊蛰始。</span></p></div> <div class="social-wrapper" data-v-1be37983><span data-v-1be37983><a href="" rel="external nofollow noopener noreferrer" target="_blank" class="social fab fa-github flat-btn" data-v-1be37983></a></span> <span data-v-1be37983><a href="mailto: 12363078673@qq.com" rel="external nofollow noopener noreferrer" target="_blank" class="social fas fa-envelope flat-btn" data-v-1be37983></a></span> <span data-v-1be37983><a href="https://blog.csdn.net/u013605060" rel="external nofollow noopener noreferrer" target="_blank" class="social fas fa-code flat-btn" data-v-1be37983></a></span> <span data-v-1be37983><a href="http://wpa.qq.com/msgrd?v=3&amp;uin=1263078673&amp;site=qq&amp;menu=yes" rel="external nofollow noopener noreferrer" target="_blank" class="social fa fa-qq flat-btn" data-v-1be37983></a></span></div></div> <div class="content" data-v-1be37983><div class="social-wrapper" data-v-1be37983><div data-v-1be37983><i class="fas fa-folder-open fa-fw" data-v-1be37983></i> <span data-v-1be37983>文章分类</span></div> <div data-v-1be37983><ul class="entry navigation" data-v-1be37983><li data-v-1be37983><a href="/categories/笔记/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>笔记</div> <div class="badge" data-v-1be37983>(14)</div></a></li><li data-v-1be37983><a href="/categories/作品集/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>作品集</div> <div class="badge" data-v-1be37983>(1)</div></a></li><li data-v-1be37983><a href="/categories/随笔/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>随笔</div> <div class="badge" data-v-1be37983>(1)</div></a></li><li data-v-1be37983><a href="/categories/喵喵/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>喵喵</div> <div class="badge" data-v-1be37983>(2)</div></a></li><li data-v-1be37983><a href="/categories/创作集/" id="blogcategoriesmac" class="flat-box" data-v-1be37983><div class="name" data-v-1be37983>创作集</div> <div class="badge" data-v-1be37983>(1)</div></a></li></ul></div></div></div> <div class="content" data-v-1be37983><div class="social-wrapper" data-v-1be37983><div data-v-1be37983><i class="fas fa-tags fa-fw" data-v-1be37983></i> <span data-v-1be37983>热门标签</span></div> <div class="word-cloud" data-v-1be37983><a href="/tags/jenkins/" style="font-size:15px;" data-v-1be37983>jenkins</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/vue/" style="font-size:18px;" data-v-1be37983>vue</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/JS/" style="font-size:24px;" data-v-1be37983>JS</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/JAVA/" style="font-size:15px;" data-v-1be37983>JAVA</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/Trilateration/" style="font-size:15px;" data-v-1be37983>Trilateration</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/Google/" style="font-size:15px;" data-v-1be37983>Google</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/pjax/" style="font-size:15px;" data-v-1be37983>pjax</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E7%94%B5%E5%BD%B1/" style="font-size:15px;" data-v-1be37983>电影</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E5%85%AB%E4%BD%B0/" style="font-size:15px;" data-v-1be37983>八佰</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E5%89%8D%E7%AB%AF/" style="font-size:18px;" data-v-1be37983>前端</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/css/" style="font-size:18px;" data-v-1be37983>css</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/docker/" style="font-size:15px;" data-v-1be37983>docker</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/nginx/" style="font-size:18px;" data-v-1be37983>nginx</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/rtmp/" style="font-size:15px;" data-v-1be37983>rtmp</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/ffmpeg/" style="font-size:18px;" data-v-1be37983>ffmpeg</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/element-ui/" style="font-size:15px;" data-v-1be37983>element-ui</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/nodejs/" style="font-size:15px;" data-v-1be37983>nodejs</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/shake/" style="font-size:15px;" data-v-1be37983>shake</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/DoraemonKit/" style="font-size:15px;" data-v-1be37983>DoraemonKit</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E6%BB%B4%E6%BB%B4/" style="font-size:15px;" data-v-1be37983>滴滴</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/BIO/NIO/AIO/" style="font-size:15px;" data-v-1be37983>BIO/NIO/AIO</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/%E6%8F%92%E4%BB%B6/" style="font-size:15px;" data-v-1be37983>插件</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/HTTP/HTTPS/" style="font-size:15px;" data-v-1be37983>HTTP/HTTPS</a></div><div class="word-cloud" data-v-1be37983><a href="/tags/TCPIP/" style="font-size:15px;" data-v-1be37983>TCPIP</a></div></div></div> <div class="content" data-v-1be37983><div class="social-wrapper" data-v-1be37983><div data-v-1be37983><i class="fas fa-bullhorn fa-fw" data-v-1be37983></i> <span data-v-1be37983>公告</span></div> <div data-v-1be37983>
                        本站使用VuePress创建全站，还在不断完善中
                    </div></div></div> <div class="content" data-v-1be37983><div class="social-wrapper" data-v-1be37983><div data-v-1be37983><i class="fas fa-award fa-fw" data-v-1be37983></i> <span data-v-1be37983>站点信息</span></div> <div class="webinfo" data-v-1be37983><div class="webinfo-item" data-v-1be37983><div data-v-1be37983>文章数目：</div> <div data-v-1be37983>58 篇</div></div> <div class="webinfo-item" data-v-1be37983><div data-v-1be37983>已运行时间：</div> <div id="webinfo-runtime-count" data-v-1be37983>162 天</div></div> <div class="webinfo-item" data-v-1be37983><div data-v-1be37983>更新时间时间：</div> <div id="webinfo-runtime-count" data-v-1be37983>3 天前更新</div></div></div></div></div></div></div></div></div></div></div></div><div class="global-ui"></div></div>
<script src="/assets/js/app.8e64649f.js" defer></script><script src="/assets/js/17.9b1a1e45.js" defer></script><script src="/assets/js/4.84c4889c.js" defer></script><script src="/assets/js/40.76c692f0.js" defer></script>
<!-- 加入音乐-->
<div style="max-width: 750px;margin: 0 auto;padding: 40px;display: none;" id="meetingJs">
    <meting-js server="netease" type="playlist" id="567087780" list-max-height=150px></meting-js>
</div>
<!--全屏遮挡-->
<div class="fullScreen" style=""></div>

<canvas width="1413" height="968"
        style="position: fixed; left: 0px; top: 0px; z-index: 2147483647; pointer-events: none;"></canvas>
<!--鼠标特效-->
<script src="https://cdn.jsdelivr.net/gh/zyoushuo/Blog/hexo/js/mouse_click.js"></script>
<script>
    // 写一个简单的pjax，适配于vuepress
    $(function () {
        function pjax(href, type) {
            //为了seo的优化，不支持方法直接跳转
            if (!history.pushState) {
                window.location.href = href;
            }
            let newHref = href;
            $.ajax({
                url: newHref, success: function (result) {
                    let resultObj = $(result);
                    //获取标题
                    let newTitle = resultObj.filter("title").text();
                    //循环Script标签，重新加载拥有defer的
                    $("script[defer]").remove();
                    $(result).filter('script[defer]').each(function () {
                        $("body").append(this.outerHTML);
                    })
                    $("#main-body-pjax").after("<div style='display: none;' id='main-body-pjax-other' class='"+$("#main-body-pjax").attr('class')+"'></div>");
                    $("#main-body-pjax-other")[0].innerHTML = resultObj.find("div[id=main-body-pjax]").innerHTML;
                    let state = ({
                        url: newHref, title: newTitle
                    });
                    if (type === 1) {
                        window.history.pushState(state, newTitle, newHref);
                    }
                    document.title = newTitle
                    //滚回顶部
                    // $('html, body').animate({scrollTop: 0}, 'slow');
                    //背景再次被重置
                    if (window.localStorage.getItem('cutoverColor') === "false") {
                        $(".fullScreen").css("background","#000")
                    }
                }
            });
        }

        // 手写一个简易版本的pjax，适用于vuepress
        $('body').on('click', 'a', function (e) {
            e.preventDefault();
            if (typeof $(this).attr("href") != "undefined") {
                pjax($(this).attr("href"), 1);
            }
        })
        window.addEventListener('popstate', function (evt) {
            let oldHref = evt.state.url;
            pjax(oldHref, 0);
        }, false);
    })


    window.onload = function () {
        //防止哔哔哔模块不显示
        bbtalk.init({
            appId: "gbNUwY2ePs3khwpWCJvSNMC5-MdYXbMMI",
            appKey: "ObQ0ANDmaRwvTREmMpzN4WNv",
            serverURLs: 'https://gbnuwy2e.api.lncldglobal.com'
        })
        //音乐模块显示
        $("#meetingJs").show();
        //背景切换图
        $.backstretch(
            ["https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/006.jpg",
                "https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/051.jpg",
                "https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/034.jpg",
                "https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg",
                "https://api.mtyqx.cn/api/random.php",
            ], {
                fade: 750, duration: 4000, speed: 500
            }
        );
        //头部，返回到顶部展示，右侧菜单的展示规则
        let t = document.documentElement.scrollTop || document.body.scrollTop;
        headShow(t);
        backTopShow(t);
        rightPageMenuShow(t);
        //事件委托 (触发跳转)文章导航
        try {
            $("body").on('click', '.navigationContent', function (event) {
                let id = event.target.getElementsByTagName('a')[0].id;
                scroll(0, document.getElementById(id).offsetTop - 85);
            })
        } catch (e) {
        }
    }

    //移动滚动条
    function scroll(currentY, targetY) {
        // 计算需要移动的距离
        let needScrollTop = targetY - currentY
        let _currentY = currentY
        setTimeout(() => {
            // 一次调用滑动帧数，每次调用会不一样
            const dist = Math.ceil(needScrollTop / 10)
            _currentY += dist
            window.scrollTo(_currentY, currentY)
            // 如果移动幅度小于十个像素，直接移动，否则递归调用，实现动画效果
            if (needScrollTop > 10 || needScrollTop < -10) {
                scroll(_currentY, targetY)
            } else {
                window.scrollTo(_currentY, targetY)
            }
        }, 1)
    }

    /*监听滚动条，显示或者隐藏某些元素（右侧文章锚点和头部）*/
    window.onscroll = function () {
        let t = document.documentElement.scrollTop || document.body.scrollTop;
        headShow(t);
        backTopShow(t);
        rightPageMenuShow(t);
    }

    function headShow(t) {
        let container = document.querySelector('.container');//container 显示
        let height = (document.querySelector('.homeCover').offsetHeight) -
            (document.querySelector('.container').style.height);
        container.style.display = (t >= (height - 50)) ? "block" : "none";
    }

    function backTopShow(t) {
        try {
            let backTop = document.querySelector('.footer-up');//footer-up 显示
            backTop.style.display = (t >= 30) ? "block" : "none";
        } catch (e) {
        }
    }

    function rightPageMenuShow(t) {
        try {
            let rightPageMenu = document.querySelector('.paperMenu');//footer-up 显示
            rightPageMenu.className = (t >= 10) ? "content paperMenu suspension" : "content paperMenu";
        } catch (e) {
        }
    }


</script>


<script>
    //暗黑模式
    let cutoverColor = false;
    $(function () {
        if (window.localStorage.getItem('cutoverColor') === "false") {
            //线程独占
            setTimeout(function () {
                darkMode();
            }, 0);
        }
        $("body").on('click', '.cutover', function () {
            darkMode();
        })
    })

    function darkMode() {
        cutoverColor = !cutoverColor;
        window.localStorage.setItem('cutoverColor', !cutoverColor);
        if (cutoverColor) {
            document.documentElement.style.setProperty('--main', '#515a6e');
            document.documentElement.style.setProperty('--mainfont', '#fff');
            document.documentElement.style.setProperty('--headfont', '#fff');
            document.documentElement.style.setProperty('--color-list', '#fff');
            document.documentElement.style.setProperty('--color-tag', '#fff');
            $(".fullScreen").css("background","#000");
        } else {
            document.documentElement.style.setProperty('--main', '#ffff');
            document.documentElement.style.setProperty('--mainfont', '#515a6e');
            document.documentElement.style.setProperty('--headfont', '#2c3e50');
            document.documentElement.style.setProperty('--color-list', '#666');
            document.documentElement.style.setProperty('--color-tag', '#999');
            $(".fullScreen").css("background","");
        }
    }
</script>

<style>
    a {
        text-decoration: none
    }

    body {
        margin: 0 auto;
    }backstretch-item

    .fullScreen {
        left: 0px;
        top: 0px;
        overflow: hidden;
        margin: 0px;
        padding: 0px;
        height: 100%;
        width: 100vw;
        z-index: -999998;
        position: fixed;
    }
</style>
</body>
</html>
